package com.bright.ghj.overt.manager.impl;

import com.bright.ghj.common.pojo.dto.PageDTO;
import com.bright.ghj.common.util.StringUtil;
import com.bright.ghj.overt.converter.AsyncMessageConverter;
import com.bright.ghj.overt.enums.AsyncTaskExecInfo;
import com.bright.ghj.overt.manager.AsyncMessageManager;
import com.bright.ghj.overt.pojo.dto.AsyncMessageDTO;
import com.bright.ghj.overt.pojo.po.primary.AsyncMessage;
import com.bright.ghj.overt.pojo.query.AsyncTaskMassageQuery;
import com.bright.ghj.overt.repository.primary.AsyncMessageRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author Tz
 * @date 2024/01/22 15:03
 * @Description 异步消息的Manager 实现
 */
@Component
@RequiredArgsConstructor
public class AsyncMessageManagerImpl implements AsyncMessageManager {

    private final AsyncMessageRepository asyncMessageRepository;
    private final AsyncMessageConverter asyncMessageConverter;

    /**
     * 保存异步任务消息
     *
     * @param asyncMessageDTO 异步任务消息的DTO
     * @return                异步任务消息的DTO
     */
    @Override
    public AsyncMessageDTO save(AsyncMessageDTO asyncMessageDTO) {
        AsyncMessage asyncMessage = asyncMessageConverter.dtoConvertPO(asyncMessageDTO);
        AsyncMessage save = asyncMessageRepository.save(asyncMessage);
        return asyncMessageConverter.poConvertDTO(save);
    }

    /**
     * 根据id查询异步任务消息
     *
     * @param id 主键
     * @return   异步任务消息DTO
     */
    @Override
    public AsyncMessageDTO getById(Integer id) {
        Optional<AsyncMessage> asyncMessageOptional = asyncMessageRepository.findById(id);
        if (!asyncMessageOptional.isPresent()) {
            throw new RuntimeException("无提交信息!");
        }
        return asyncMessageConverter.poConvertDTO(asyncMessageOptional.get());
    }

    /**
     * 根据id撤回当前任务
     *
     * @param id 主键id
     * @return   返回结果数
     */
    @Override
    public Integer revokeAsyncTask(Integer id) {
        return asyncMessageRepository.revokeAsyncTask(id);
    }

    /**
     * 根据条件获取异步任务消息列表
     *
     * @param asyncTaskMassageQuery 查询条件
     * @param pageable              分页条件
     * @return                      异步消息列表
     */
    @Override
    public PageDTO<AsyncMessageDTO> pageAsyncMessage(AsyncTaskMassageQuery asyncTaskMassageQuery, Pageable pageable) {

        Page<AsyncMessage> page = asyncMessageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> ps = new ArrayList<>();
            if (StringUtil.isNotBlank(asyncTaskMassageQuery.getUsername())) {
                ps.add(criteriaBuilder.equal(root.get("username"), asyncTaskMassageQuery.getUsername()));
            }
            if (StringUtil.isNotBlank(asyncTaskMassageQuery.getTaskType())) {
                ps.add(criteriaBuilder.equal(root.get("taskType"), asyncTaskMassageQuery.getTaskType()));
            }
            //根据状态类别条件查询执行状态
            if (asyncTaskMassageQuery.getStatusCategory() != null) {
                ps.add(criteriaBuilder.in(root.get("execStatus")).value(AsyncTaskExecInfo.getStatusFromCategory(asyncTaskMassageQuery.getStatusCategory())));
            }
            if (asyncTaskMassageQuery.getReadFlag() != null) {
                ps.add(criteriaBuilder.equal(root.get("readFlag"), asyncTaskMassageQuery.getReadFlag()));
            }
            criteriaQuery.where(ps.toArray(new Predicate[0]));
            criteriaQuery.orderBy(criteriaBuilder.desc(root.get("updatedTime")));
            return criteriaQuery.getRestriction();
        }, pageable);

        List<AsyncMessageDTO> list = asyncMessageConverter.poConvertDTO(page.getContent());

        return PageDTO.of(page.getTotalElements(), page.getTotalPages(), list);
    }

    /**
     * 根据keyword集合查询异步消息列表
     *
     * @param keywords keyword集合
     * @return         异步消息列表
     */
    @Override
    public List<AsyncMessageDTO> listAsyncMessageByKeywords(List<String> keywords) {
        List<AsyncMessage> asyncMessages = asyncMessageRepository.listAsyncMessageByKeywords(keywords);
        return asyncMessageConverter.poConvertDTO(asyncMessages);
    }

    /**
     * 一键已读
     *
     * @param execStatus 需要已读的状态列表
     * @param username   需要已读的用户
     * @return 已读记录数
     */
    @Override
    public Integer oneClickRead(List<Integer> execStatus, String username) {
        return asyncMessageRepository.oneClickRead(execStatus, username);
    }

    /**
     * 阅读一条未读消息
     *
     * @param id 主键
     * @return 读取结果
     */
    @Override
    public Integer read(Integer id) {
        return asyncMessageRepository.read(id);
    }
}
